package com.beone.admin.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.base.SuperServiceImpl;
import com.base.common.util.DateUtil;
import com.beone.admin.entity.BaseUser;
import com.beone.admin.entity.Task;
import com.beone.admin.entity.TaskAttachment;
import com.beone.admin.entity.TaskType;
import com.beone.admin.form.TaskAttachmentForm;
import com.beone.admin.form.TaskForm;
import com.beone.admin.mapper.TaskMapper;
import com.beone.admin.query.TaskQuery;
import com.beone.admin.service.BaseUserService;
import com.beone.admin.service.TaskAttachmentService;
import com.beone.admin.service.TaskService;
import com.beone.admin.service.TaskTypeService;
import com.beone.admin.utils.PaginationGatagridTable;
import com.beone.admin.utils.ServiceUtils;
import com.beone.admin.vo.TaskStatisticVO;
import com.beone.admin.vo.TaskVO;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 * @Title 任务反馈表 服务实现类
 * @Author 秦波
 * @Version 1.0 on 2019-05-18
 * @Copyright 贝旺科权
 */
@Service
public class TaskServiceImpl extends SuperServiceImpl<TaskMapper, Task> implements TaskService {

    @Autowired
    private TaskAttachmentService taskAttachmentService;
    @Autowired
    private BaseUserService baseUserService;
    @Autowired
    private TaskTypeService taskTypeService;

    /**
    * 分页显示任务反馈表列表
    * @param query
    * @return
    */
    @Override
    public PaginationGatagridTable getTaskPagination(TaskQuery query){
        EntityWrapper<Task> ew = new EntityWrapper<>();
        Page<Task> page = new Page<>(query.getPage(), query.getRows());
        ew.orderBy("create_time", false);
        if(null != query.getType()){
            if(query.getType() == 1){
                ew.ge("task_time", DateUtil.getDayBegin());
                ew.le("task_time", DateUtil.getDayEnd());
            }else if(query.getType() == 2){
                ew.ge("task_time", DateUtil.getBeginDayOfWeek());
                ew.le("task_time", DateUtil.getEndDayOfWeek());
            }else if(query.getType() == 3){
                ew.ge("task_time", DateUtil.getBeginDayOfMonth());
                ew.le("task_time", DateUtil.getEndDayOfMonth());
            }
        }
        if (StringUtils.isNotBlank(query.getDescr())) {
            ew.like("descr", query.getDescr());
        }
        if (null != query.getUserId()) {
            ew.eq("create_user_id", query.getUserId());
        }
        if (null != query.getStartTime()) {
            ew.ge("task_time", query.getStartTime());
        }
        if (null != query.getEndTime()) {
            ew.le("task_time", query.getEndTime());
        }
        if (null != query.getTaskType()) {
            ew.eq("type", query.getTaskType());
        }
        if (null != query.getFinishTag()) {
            ew.eq("finish_tag", query.getFinishTag());
        }
        if (null != query.getFinishTag()) {
            ew.eq("finish_tag", query.getFinishTag());
        }
        if (null != query.getId()) {
            ew.eq("id", query.getId());
        }
        List<Task> rows = baseMapper.selectPage(page, ew);
        return ServiceUtils.createGatagridTableJson(page, this.convertList2VO(rows));
    }

    @Override
    public boolean insertOrUpdate(TaskForm form) {
        Task task = new Task();
        Date now = new Date();
        BeanUtils.copyProperties(form, task);
        if (form.getId() != null) {
            //taskAttachmentService.deleteByTaskId(form.getId());
            task.setUpdateTime(now);
            task.setFinishTag(1);
            if (form.getFinishTag()) {
                task.setFinishTime(now);
            }
        } else {
            task.setCreateTime(now);
            task.setCreateUserId(form.getUserId());
        }
        boolean flag = super.insertOrUpdate(task);
        if (flag) {
            this.addTaskAttachments(form.getAttachmentList(), task.getId());
        }
        return flag;
    }

    @Override
    public TaskStatisticVO getStatistics(Integer userId) {
        TaskStatisticVO vo = new TaskStatisticVO();
        vo.setUserId(userId);
        this.buildStatistic(vo);
        return vo;
    }

    /**
     * 转换对象列表，补全属性
     * @param taskList
     * @return
     */
    private List<TaskVO> convertList2VO(List<Task> taskList) {
        if (CollectionUtils.isEmpty(taskList)) {
            return Collections.emptyList();
        }
        List<TaskVO> voList = new ArrayList<>(taskList.size());
        taskList.stream().forEach(e -> {
            TaskVO vo = new TaskVO();
            BeanUtils.copyProperties(e, vo);
            BaseUser user = baseUserService.selectById(1);
            TaskType taskType = taskTypeService.selectById(e.getType());
            vo.setTypeName(taskType.getName());
            vo.setUserName(user.getUserName());
            vo.setAttachmentList(taskAttachmentService.selectListByTaskId(e.getId()));
            voList.add(vo);
        });
        return voList;
    }

    /**
     * 添加附件
     * @author Pagenny
     * @date 2019-05-18 20:45
     * @param attachments
     * @param taskId
     * @return
     */
    private void addTaskAttachments(List<TaskAttachmentForm> attachments, Integer taskId) {
        if (!CollectionUtils.isEmpty(attachments) && taskId != null) {
            Date now = new Date();
            List<TaskAttachment> attachmentList = new ArrayList<>(attachments.size());
            attachments.forEach(e -> {
                TaskAttachment t = new TaskAttachment();
                BeanUtils.copyProperties(e, t);
                t.setTaskId(taskId);
                t.setCreateTime(now);
                attachmentList.add(t);
            });
            taskAttachmentService.insertBatch(attachmentList);
        }
    }

    /**
     * <pre>
     * 组装统计信息：
     *      本天：零点到现在的统计
     *      本周：周一零点到现在的统计
     *      本月：1号零点到现在的统计
     * </pre>
     * @param vo
     */
    private void buildStatistic(TaskStatisticVO vo) {
        int tasksDay = 0, finishTasksDay = 0,
            tasksWeek = 0, finishTasksWeek = 0,
            tasksMonth = 0, finishTasksMonth = 0;

        Date now = new Date();
        EntityWrapper<Task> ew = new EntityWrapper<>();
        ew.eq("create_user_id", vo.getUserId());
        // 考虑数据量不会太大，将指定用户近31天数据全部取出一次性处理
        ew.ge("task_time", DateUtil.addDays(now, -31));
        List<Task> taskList = baseMapper.selectList(ew);

        if (!CollectionUtils.isEmpty(taskList)) {
            Date beginTimeDay = DateUtil.getZeroTimeOfDay(now),
                 beginTimeWeek = DateUtil.getFirstDayOfWeek(now, true),
                 beginTimeMonth = DateUtil.getFirstDayOfMonth(now);
            for (Task task : taskList) {
                Date taskTime = task.getTaskTime();
                boolean isFinished = task.getFinishTag() == 1;
                if (beginTimeDay.compareTo(taskTime) <= 0) {
                    tasksDay++;
                    if (isFinished) finishTasksDay++;
                }
                if (beginTimeWeek.compareTo(taskTime) <= 0) {
                    tasksWeek++;
                    if (isFinished) finishTasksWeek++;
                }
                if (beginTimeMonth.compareTo(taskTime) <= 0) {
                    tasksMonth++;
                    if (isFinished) finishTasksMonth++;
                }
            }
        }

        vo.setTaskAmountDay(tasksDay);
        vo.setFinishTaskAmountDay(finishTasksDay);
        vo.setTaskAmountWeek(tasksWeek);
        vo.setFinishTaskAmountWeek(finishTasksWeek);
        vo.setTaskAmountMonth(tasksMonth);
        vo.setFinishTaskAmountMonth(finishTasksMonth);
    }
}
